package com.koron.common.core.business.todoApproval.templates;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.business.configsettings.utils.ConfigInfoTool;
import com.koron.common.core.business.workflow.bean.param.SubmitParam;
import com.koron.common.core.business.workflow.bean.po.SysWorkflow;
import com.koron.common.core.business.workflow.service.SysWorkflowService;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.message.MessageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author jzp
 * @since 2022/10/11
 */
@Slf4j
@Service
public class TodoApprovalHandler {

    @Resource
    private TodoApprovalModel todoApprovalModel;

    @Autowired
    SysWorkflowService sysWorkflowService;

    @Autowired
    private MessageUtil messageUtil;

    private final ExecutorService service = Executors.newFixedThreadPool(5);

    public void startTodo(String bizId, String title, String accountstr, String createBy, String processCode, Date date, String modelName) {
        if (!allowTodo()) {
            return;
        }
        log.info("OA待办发起，id:{}, title:{}, accountstr:{}, processCode: {}", bizId, title, accountstr, processCode);
        String pcUrl = messageUtil.getRoutePath() + "upComingCenter/upComing";
        // 禁止移动端访问
        // String mobileUrl = messageUtil.generateQywxHref(pcUrl);
        //String mobileUrl = messageUtil.getRoutePath() + "noMobile";
        try {
            // 构建链接
            pcUrl = messageUtil.generateEamIdHref("transmit_" + processCode, bizId);
            // String eamRedirectHref = messageUtil.generateEamRedirectHref(pcUrl);
            // mobileUrl = messageUtil.generateQywxHref(eamRedirectHref);
        }  catch (Exception e) {
            log.error(e.getMessage());
        }
        String mobileUrl = pcUrl;
        log.info("OA-待办移动端地址：" + mobileUrl);
        log.info("OA-pc端地址：" + pcUrl);
        Assert.hasText(accountstr, "待办处理人不能为空");
        String[] split = accountstr.split("[,;&]");
        String res = todoApprovalModel.startTodo(bizId, title, pcUrl, mobileUrl, Arrays.asList(split), createBy, date, modelName);
        dealResponse(res);
    }

    /**
     * 创建待办
     */
    public void createTodo(String bizId, String title, String accountstr, String createBy, String processCode, Date date, String modelName) {
        if (!allowTodo()) {
            return;
        }
        log.info("OA待办创建，id:{}, title:{}, accountstr:{}, processCode: {}", bizId, title, accountstr, processCode);
        String pcUrl = messageUtil.getRoutePath() + "upComingCenter/upComing";
        // 禁止移动端访问
        // String mobileUrl = messageUtil.generateQywxHref(pcUrl);
        try {
            // 构建链接
            pcUrl = messageUtil.generateEamIdHref("transmit_" + processCode, bizId);
            // String eamRedirectHref = messageUtil.generateEamRedirectHref(pcUrl);
            // mobileUrl = messageUtil.generateQywxHref(eamRedirectHref);
        }  catch (Exception e) {
            log.error(e.getMessage());
        }
        String mobileUrl = pcUrl;
        log.info("OA-待办移动端地址：" + mobileUrl);
        log.info("OA-pc端地址：" + pcUrl);
        Assert.hasText(accountstr, "待办处理人不能为空");
        String[] split = accountstr.split("[,;&]");
        String res = todoApprovalModel.sendTodo(bizId, title, pcUrl, mobileUrl, Arrays.asList(split), createBy, date, modelName);
        dealResponse(res);
    }

    /**
     * 该业务所有待办转已办
     */
    public void allDone(String bizId, String accountstr, String modelName) {
        if (!allowTodo()) {
            return;
        }
        log.info("OA待办所有人员所属转已办，id:{}", bizId);
        String res;
        if (accountstr == null) {
            res = todoApprovalModel.setTodoDone(bizId, null, modelName);
        } else {
            String[] split = accountstr.split("[,;&]");
            res = todoApprovalModel.setTodoDone(bizId, Arrays.asList(split), modelName);
        }
        dealResponse(res);
    }

    /**
     * 该业务指定人员转已办
     */
    public void accountDone(String bizId, String accountstr, String modelName) {
        if (!allowTodo()) {
            return;
        }
        log.info("OA待办当前人员所属转已办，id:{}, accountstr:{}", bizId, accountstr);
        Assert.hasText(accountstr, "已办处理人不能为空");
        String[] split = accountstr.split("[,;&]");
        String res = todoApprovalModel.setAccountsTodoDone(bizId, Arrays.asList(split), modelName);
        dealResponse(res);
    }

    /**
     * 删除指定业务待办
     */
    public void deleteTodo(String bizId, String modelName) {
        if (!allowTodo()) {
            return;
        }
        log.info("OA待办删除，id:{}", bizId);
        String res = todoApprovalModel.deleteTodo(bizId, modelName);
        dealResponse(res);
    }

    public JSONObject getTodo(String accountstr, String rowSize, String pageNo, String title, String beginTime, String endTime, String modelName) {
        Assert.hasText(accountstr, "已办处理人不能为空");
        String[] split = accountstr.split("[,;&]");
        String res = todoApprovalModel.getTodo(Arrays.asList(split), rowSize, pageNo, 0, title, beginTime, endTime, modelName);
        JSONObject result = JSONUtil.parseObj(res);
        if (result.getInt("returnState") == 1) {
            throw new IllegalArgumentException("待审服务异常：" + result.getStr("message"));
        }

        JSONObject message = result.getJSONObject("message");
        if (message != null && message.getStr("docs") != null) {
            return message;
        }
        return null;
    }

    public JSONObject getTodoDone(String accountstr, String rowSize, String pageNo, String title, String beginTime, String endTime, String modelName) {
        Assert.hasText(accountstr, "已办处理人不能为空");
        String[] split = accountstr.split("[,;&]");
        String res = todoApprovalModel.getTodo(Arrays.asList(split), rowSize, pageNo, -1, title, beginTime, endTime, modelName);
        JSONObject result = JSONUtil.parseObj(res);
        if (result.getInt("returnState") == 1) {
            throw new IllegalArgumentException("待审服务异常：" + result.getStr("message"));
        }

        JSONObject message = result.getJSONObject("message");
        if (message != null && message.getStr("docs") != null) {
            return message;
        }
        return null;
    }



    public void submit(String bizId, String title, SysWorkflow sysWorkflow , boolean isNextNode, String accountstr, SubmitParam submitParam, Date date, String modelName) {
        if (!allowTodo()) {
            return;
        }
        service.execute(() -> {
            try {
                // @TODO 2023-08-23 用于后续待办根据流程创建时间判断，参考GdhWaterTodoApprovalModel.getCompatibilityAppName
                EamUser eamUser = ThreadLocalContext.get();
                eamUser.setCreateTime(sysWorkflow.getCreateTime());
                // 不明其意，去掉这两行代码
                // String res = todoApprovalModel.deleteTodo(bizId, modelName);
                // dealResponse(res);

                // 如果流转到下一个节点
                if (isNextNode) {
                    allDone(bizId, submitParam.getOperator(), modelName);
                    // 如果下一个节点处理人不为空，则创建待办
                    if (StrUtil.isNotEmpty(accountstr)) {
                        createTodo(bizId, title, accountstr, submitParam.getOperator(), sysWorkflow.getProcessCode(), date, modelName);
                    }
                } else if (submitParam.getOperation() == 2) {
                    // 如果是转办，
                    allDone(bizId, submitParam.getOperator(), modelName);
                    // 创建待办
                    createTodo(bizId, title, submitParam.getRelatedUser(), submitParam.getOperator(), sysWorkflow.getProcessCode(), date, modelName);
                } else if (submitParam.getOperation() == 4) {
                    // 如果是沟通
                    createTodo(bizId, title, submitParam.getRelatedUser(), submitParam.getOperator(), sysWorkflow.getProcessCode(), date, modelName);
                } else if (submitParam.getOperation() == 128) {
                    // 如果是取消沟通
                    accountDone(bizId, submitParam.getRelatedUser(), modelName);
                } else {
                    // 如果停留在当前节点，而且不是转办和沟通，那就是（通过、驳回、回复沟通等），当前处理人转已办
                    accountDone(bizId, submitParam.getOperator(), modelName);
                }
            } catch (Exception e) {
                log.error(e.getMessage());
            } finally {
                ThreadLocalContext.clear(); // 清除tl
            }
        });
    }

    private boolean allowTodo() {
        Map<String, String> config = ConfigInfoTool.getConfigByCode("common", "upComing");
        String enableTodo = config.get("enableTodo");
        return "1".equals(enableTodo);
    }

    /**
     * returnState	返回状态	数字(int)	不允许为空
     * 0:表示未操作
     * 1:表示操作失败
     * 2:表示操作成功
     *
     * message	返回信息	字符串(String)	可为空
     * 返回状态值为0时，该值返回空。
     * 返回状态值为1时，该值错误信息。
     * 返回状态值为2时， 该值返回空。
     *
     * @param res 响应结果
     */
    private void dealResponse(String res) {
        if (res == null){
            return;
        }

        JSONObject result = JSONUtil.parseObj(res);
        if (result.getInt("returnState") == 1) {
            throw new IllegalArgumentException("待审服务异常：" + result.getStr("message"));
        }
    }

}
